package pcp

import (
	"crypto/aes"
	"crypto/cipher"
	"encoding/base64"
	"fmt"
)

func AesCFBEncrypt(value, key, iv string) (rst string, err error) {
	v, i, k := []byte(value), []byte(iv), []byte(key)

	if l := len(k); l != 16 && l != 24 && l != 32 {
		err = fmt.Errorf("密钥长度必须是16、24或32字节")
		return
	}

	if len(i) != aes.BlockSize {
		err = fmt.Errorf("IV长度必须是%d字节", aes.BlockSize)
		return
	}

	stream, err := newCFBEncrypter(k, i)
	if err != nil {
		return
	}

	ciphertext := make([]byte, len(v))
	stream.XORKeyStream(ciphertext, v)

	return base64.StdEncoding.EncodeToString(ciphertext), nil
}

func AesCFBDecrypt(value, key, iv string) (rst string, err error) {
	i, k := []byte(iv), []byte(key)

	if l := len(k); l != 16 && l != 24 && l != 32 {
		err = fmt.Errorf("密钥长度必须是16、24或32字节")
		return
	}

	if len(i) != aes.BlockSize {
		err = fmt.Errorf("IV长度必须是%d字节", aes.BlockSize)
		return
	}

	stream, err := newCFBDecrypter(k, i)
	if err != nil {
		return
	}

	data, err := base64.StdEncoding.DecodeString(value)
	if err != nil {
		return
	}

	plaintext := make([]byte, len(data))
	stream.XORKeyStream(plaintext, data)

	return string(plaintext), nil
}

// 生成AES-CFB模式的加密器
func newCFBEncrypter(key, iv []byte) (cipher.Stream, error) {
	block, err := aes.NewCipher(key)
	if err != nil {
		return nil, err
	}
	return cipher.NewCTR(block, iv), nil
}

// 生成AES-CFB模式的解密器
func newCFBDecrypter(key, iv []byte) (cipher.Stream, error) {
	block, err := aes.NewCipher(key)
	if err != nil {
		return nil, err
	}
	return cipher.NewCTR(block, iv), nil
}
